//    [self.urlasset loadValuesAsynchronouslyForKeys:@[key] completionHandler:^{
//        [self prepareToPlay];
//    }];



#import "RemotePlayer.h"
#import "ResourceLoaderDelegate.h"
#import "NSURL+StreamingURL.h"
@interface RemotePlayer ()
@property(strong,nonatomic) ResourceLoaderDelegate *resourceDelegate;
@end

static NSString * const key = @"tracks";
@implementation RemotePlayer

IMSingletonM


#pragma mark - -1002失败,切换正常播放
- (void)vagetive{
    
    [self.player.currentItem removeObserver:self forKeyPath:@"status"];
    [self.player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemPlaybackStalledNotification object:nil];
    
    
    AVURLAsset *asset = [AVURLAsset assetWithURL:[self.url compenst]];
    self.resourceDelegate = [ResourceLoaderDelegate new];
    [asset.resourceLoader setDelegate:self.resourceDelegate queue:dispatch_get_main_queue()];
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    
    
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [item addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playInterupt) name:AVPlayerItemPlaybackStalledNotification object:nil];
    // !!!: 切换资源
    [self.player replaceCurrentItemWithPlayerItem:item];
    // !!!: 异步加载
    [asset loadValuesAsynchronouslyForKeys:@[key] completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self assetPrepare:asset];
        });
        
    }];
}

- (void)playWith:(NSURL *)url cachePolicy:(BOOL)policy{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(vagetive) name:URLNAGETIVE1002 object:nil];
    });
    
    if ([self.url isEqual:url]) {
        [self play];
        return;
    }
    
    self.url = url;
    
    
    
    if (policy) {
        self.url = [url streamingURL];
    }

    AVURLAsset *asset = [AVURLAsset assetWithURL:self.url];
    self.resourceDelegate = [ResourceLoaderDelegate new];
    [asset.resourceLoader setDelegate:self.resourceDelegate queue:dispatch_get_main_queue()];

    
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [item addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playInterupt) name:AVPlayerItemPlaybackStalledNotification object:nil];
    
    
    
    self.player = [AVPlayer playerWithPlayerItem:item];
    
    [asset loadValuesAsynchronouslyForKeys:@[key] completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self assetPrepare:asset];
        });

    }];
}


- (void)assetPrepare:(AVURLAsset *)asset{
    
    AVKeyValueStatus staut = [asset statusOfValueForKey:key error:nil];
    switch (staut) {
        case AVKeyValueStatusUnknown:
            
            break;
        case AVKeyValueStatusLoading:
            
            break;
        case AVKeyValueStatusLoaded:
            [self.player play];
            break;
        case AVKeyValueStatusFailed:
            
            break;
        case AVKeyValueStatusCancelled:
            
            break;
            
        default:
            break;
    }
    
}


#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] integerValue];
        if (status == AVPlayerItemStatusReadyToPlay) {
            NSLog(@"资源准备好了, 这时候播放就没有问题");
            [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(ReadyToPlay)}];
            [self.player play];
        }else {
            NSLog(@"状态未知");
            [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(Failed)}];

        }
    }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
        BOOL ptk = [change[NSKeyValueChangeNewKey] boolValue];
        if (ptk) {
            NSLog(@"当前的资源, 准备的已经足够播放了");
            [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(Play)}];
            //
//            // 用户的手动暂停的优先级最高
//            if (!_isUserPause) {
//                [self resume];
//            }else {
//
//            }

        }else {
            NSLog(@"资源还不够, 正在加载过程当中");
            [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(Loading)}];
        }
    }
}

- (void)playWithProgress:(CGFloat)progress{
    CMTime time = self.player.currentItem.duration;
    CGFloat totalSeconds = CMTimeGetSeconds(time);
    CGFloat palySeconds = totalSeconds * progress;
    CMTime playTime = CMTimeMake(palySeconds, 1);
    [self.player seekToTime:playTime completionHandler:^(BOOL finished) {
        if (finished) {
            DLOG(@"跳转播放成功");
        }else{
            DLOG(@"跳转播放失败");
        }
    }];
}

- (void)playEnd {
    NSLog(@"播放完成");
    [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(PlayEnd)}];
    [self stop];
    
}
- (void)playInterupt {
    // 来电话, 资源加载跟不上
    [[NSNotificationCenter defaultCenter]postNotificationName:PLAYSTATUCHANGEKEY object:nil userInfo:@{@"value" : @(PayPaused)}];
    NSLog(@"播放被打断");
 
}

- (CGFloat)loadProgress{
    CMTimeRange timeRange = [self.player.currentItem.loadedTimeRanges.lastObject CMTimeRangeValue];
    CMTime loadTime = CMTimeAdd(timeRange.start, timeRange.duration);
    CGFloat loadTimeSec = CMTimeGetSeconds(loadTime);
    return loadTimeSec / self.totalTime;
}

- (NSInteger)totalTime{
    return CMTimeGetSeconds(self.player.currentItem.asset.duration);
}

- (NSInteger)currentTime{
    return CMTimeGetSeconds(self.player.currentItem.currentTime);
}

- (NSString *)totalTimeFormat{
    return [NSString stringWithFormat:@"%02zd:%02zd",self.totalTime / 60,(self.totalTime % 60)];
}

- (NSString *)currentTimeFormat{
    return [NSString stringWithFormat:@"%02zd:%02zd",self.currentTime / 60,(self.currentTime % 60)];
}

- (CGFloat)progress{
    CGFloat pro = self.currentTime * 1.0 / self.totalTime ;
    return pro;
}

- (void)pause{
    [self.player pause];
}
- (void)play{
    [self.player play];
}
- (void)stop{
    self.url = [NSURL URLWithString:@" "];
    [self.player pause];
    [self.player.currentItem cancelPendingSeeks];
    [self.player.currentItem.asset cancelLoading];
    [self.player.currentItem removeObserver:self forKeyPath:@"status"];
    [self.player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemPlaybackStalledNotification object:nil];
    self.player = nil;
    
}

- (void)setMute:(BOOL)mute{
    _mute = mute;
    self.player.muted = mute;
}

- (void)setVolume:(CGFloat)volume{
    _volume = volume;
    self.player.volume = volume;
}

- (void)setRate:(CGFloat)rate{
    _rate = rate;
    self.player.rate = rate;
}


@end
